/*
Code : Dzlua
Email: 505544956@qq.com
Time : 2017/06/05
*/
#include "multi_server.h"
using namespace dzlua;

#include <vector>

struct sData
{
    cs::Conn* conn;
    int count;
};

class Server : public cs::MultiServer {
public:
    Server(int count) : cs::MultiServer(count) {}
    ~Server() {}
public:
    virtual void ConnectionEvent(cs::Conn *conn) {
        Server *me = (Server*)conn->GetThread()->tcpConnect;
        printf("new connection: %d\n", conn->GetFd());
        sData* data = new sData;
        data->conn = conn;
        data->count = 0;
        me->vec.push_back(data);
    }

    virtual void ReadEvent(cs::Conn *conn) {
        int len = conn->GetReadBufferLen();
        if (len <= 0) return;
        char* buff = new char[len+1];
        if (!buff) return;
        buff[len] = 0;
        len = conn->GetReadBuffer(buff, len);
        if (len <= 0) return;

        if (0 == strcmp(buff, "cmdcloseserver")) {
            conn->GetThread()->tcpConnect->StopRun(nullptr);
            conn->AddToWriteBuffer("close", strlen("close"));
            return;
        }

        // write to write buffer
        conn->AddToWriteBuffer(buff, len);

        //conn->MoveBufferData();
    }

    virtual void WriteEvent(cs::Conn *conn) {}

    virtual void CloseEvent(cs::Conn *conn, short events) {
        printf("connection closed: %d\n", conn->GetFd());
        for (auto it = vec.begin(); it != vec.end(); ++it) {
            if ( (*it)->conn != conn ) continue;
            delete (*it);
            vec.erase(it);
            break;
        }
    }
public:
    // called before quit(ctrl + C).
    static void QuitCb(int sig, short events, void *data) {
        printf("Catch the SIGINT signal, quit in one second\n");  
        Server *me = (Server*)data;
        timeval tv = {1, 0};
        me->StopRun(&tv);
    }

    // heartbeat: send "." to all clients per seconds.
    static void OnHeartbeat(int id, int short events, void *data) {
        Server *me = (Server*)data;
        char temp[33] = ".";
        for(int i=0; i<me->vec.size(); i++) {
            me->vec[i]->conn->AddToWriteBuffer(temp, strlen(temp));
        }
    }
private:
    std::vector<sData*> vec;
};

int main(int argc, char** argv)
{
    // use 3 thread
    Server ser(3);
    // set port
	ser.SetPort(25092);  
    // set heartbeat
    timeval tv = {10, 0};  
	ser.AddTimerEvent(&Server::OnHeartbeat, tv, false);

    // for ctrl+c to break.
    ser.AddSignalEvent(SIGINT, &Server::QuitCb);  
	
    // start
	ser.StartRun();

	printf("done\n"); 
    
    return 0;
}